
#ifndef __ATOMTRACE_COLOR_h
#define __ATOMTRACE_COLOR_h

#include "trax.hpp"

namespace AtomTrace{
    // A barebones Color class for the basic samples
    class Color {
    public:

        float R, G, B;

        Color();
        Color(const Color& copy);
        Color(float r, float g, float b);
        Color(float intens);
        Color& operator=(const Color& copy);
        Color& operator=(const float val);
        
        const Color & LoadFromGM(int addr);
        void SaveToGM(int addr);
        void SaveToGM(int addr) const;

        float r() const;
        float g() const;
        float b() const;

        const Color operator*(const Color & other) const;
        const Color operator*(float scalar) const;
        const Color & operator*=(const Color & other);
        const Color & operator*=(float scalar);

        const Color operator/(float s) const;
        const Color & operator/=(float s);

        const Color operator+(const Color & other) const;
        const Color operator-(const Color & other) const;
        const Color & operator+=(const Color & other);

        void Clamp(float cmin=0.0f, float cmax=1.0f);
        void ClampNeg(); // clamp out negative value if it is exist

        inline float Gray() const;
        inline void Set(float r, float g, float b);
        inline void Set(float intens);
        
        inline const float & operator[](int index) const;
        inline float & operator[](int index);
    //--------WARNING: These static constant varibles is not safe in TRaX ---->
      static const Color WHITE;
      static const Color BLACK;
      //-------------------------------<
    };
    
    // *************** Inline functions ********************
    // make it static ?
    inline const Color LoadColorFromGM(int address)
    {
        return Color(loadf(address, 0),
                     loadf(address, 1),
                     loadf(address, 2));
    }

    float Color::Gray() const
    {
    	return (R+G+B)/3.0f;
    }
    
    void Color::Set(float r, float g, float b)
    {
        R = r;
        G = g;
        B = b;
    }
    
    void Color::Set(float intens)
    { R=G=B=intens; }
    
    const float & Color::operator[](int index) const
    { return *(&R+index); }
    
    float & Color::operator[](int index)
    { return *(&R+index); }
    
}// namespace AtomTrace


#endif //__ATOMTRACE_COLOR_h
